package com.xcity.tools;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.xcity.db.entity.Item;

import naga.x.util.IOUtils;
import naga.x.util.IOUtils.LineReaderListener;
import naga.x.util.NumberUtils;
import naga.x.util.StringUtils;

public class TempDataParser {

	static class Build extends com.xcity.db.entity.Build {
		@JSONField(name = "0")
		private int id;
		@Override
		public void setId(int id) {
			this.id = id;
		}
		@Override
		public int getId() {
			return id;
		}
	}
	
	static class Player {
		long id;
		long userId;
		String name;
		byte sex;
		int level;
		long gold;
		int stone;
		String createTime;
		String lastLoginTime;
		List<Build> buildings;
		List<Long> friends;
		public long getId() {
			return id;
		}
		public void setId(long id) {
			this.id = id;
		}
		public long getUserId() {
			return userId;
		}
		public void setUserId(long userId) {
			this.userId = userId;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public byte getSex() {
			return sex;
		}
		public void setSex(byte sex) {
			this.sex = sex;
		}
		public int getLevel() {
			return level;
		}
		public void setLevel(int level) {
			this.level = level;
		}
		public long getGold() {
			return gold;
		}
		public void setGold(long gold) {
			this.gold = gold;
		}
		public int getStone() {
			return stone;
		}
		public void setStone(int stone) {
			this.stone = stone;
		}
		public String getCreateTime() {
			return createTime;
		}
		public void setCreateTime(String createTime) {
			this.createTime = createTime;
		}
		public String getLastLoginTime() {
			return lastLoginTime;
		}
		public void setLastLoginTime(String lastLoginTime) {
			this.lastLoginTime = lastLoginTime;
		}
		public List<Build> getBuildings() {
			return buildings;
		}
		public void setBuildings(String buildings) {
			this.buildings = JSON.parseArray(buildings, Build.class);
			if (this.buildings == null) {
				this.buildings = Collections.emptyList();
			}
		}
		public List<Long> getFriends() {
			return friends;
		}
		public void setFriends(String friends) {
			this.friends = JSON.parseArray(friends, Long.class);
			if (this.friends == null) {
				this.friends = Collections.emptyList();
			}
		}
	}
	
	static class GameItem extends Item {}
	
	static class BuildTemplate {
		int id;
		String name;
		BuildTemplate(String line, Map map) {
			String[] strs = StringUtils.split(line, "\t");
			this.id = NumberUtils.parseInt(strs[0].trim());
			this.name = strs[1].trim();
			map.put(id, this);
		}
	}
	
	static class GameItemTemplate extends BuildTemplate {
		GameItemTemplate(String line, Map map) {
			super(line, map);
		}
	}
	
	static Map<Integer, BuildTemplate> buildTemplates = new LinkedHashMap<Integer, BuildTemplate>();
	static Map<Integer, GameItemTemplate> gameItemTemplates = new LinkedHashMap<Integer, GameItemTemplate>();
	static Map<Long, List<GameItem>> items = new LinkedHashMap<Long, List<GameItem>>(20480);
	
	static List<Player> players = Collections.emptyList();//new LinkedList<Player>();
	
	static File parent = new File("C:/Users/yang.li/Desktop/test");
	
	public static void main(String[] args) {
		long t = System.currentTimeMillis();
		System.out.println("start");
		run();
		t = System.currentTimeMillis() - t;
		System.out.println("ok=" + (t / 1000) + " s.");
	}
	
	static void run() {
		IOUtils.read(new File(parent, "build.template.txt"), IOUtils.UTF8, new LineReaderListener() {
			public boolean readLine(String line) {
				new BuildTemplate(line, buildTemplates);
				return true;
			}
		});
		IOUtils.read(new File(parent, "item.template.txt"), IOUtils.UTF8, new LineReaderListener() {
			public boolean readLine(String line) {
				new GameItemTemplate(line, gameItemTemplates);
				return true;
			}
		});
//		System.out.println(IOUtils.read(new File(parent, "city_pro_player.json"), IOUtils.UTF8).substring(244, 344));
		players = JSON.parseArray(IOUtils.read(new File(parent, "city_pro_player.json"), IOUtils.UTF8), Player.class);
		List<GameItem> itemList = JSON.parseArray(IOUtils.read(new File(parent, "city_pro_item.json"), IOUtils.UTF8), GameItem.class);
		for (GameItem item : itemList) {
			List<GameItem> list = items.get(item.getOwnerId());
			if (list == null) {
				list = new LinkedList<GameItem>();
				items.put(item.getOwnerId(), list);
			}
			list.add(item);
		}
		
		stat();
	}
	
	static void stat() {
		XSSFWorkbook book = new XSSFWorkbook();
		try {
			Sheet sheet = book.createSheet("parsed");
			stat(sheet);
			File file = new File(parent, "parsed.xlsx");
			IOUtils.createNewFile(file);
			book.write(new FileOutputStream(file));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(book);
		}
	}

	static void stat(Sheet sheet) {
		int rownum = 0, colnum = 0;
		// header
		Row row = sheet.createRow(rownum++);
		Cell cell = row.createCell(colnum++);
		cell.setCellValue("玩家id");
		cell = row.createCell(colnum++);
		cell.setCellValue("玩家名");
		cell = row.createCell(colnum++);
		cell.setCellValue("性别");
		cell = row.createCell(colnum++);
		cell.setCellValue("等级");
		cell = row.createCell(colnum++);
		cell.setCellValue("现金");
		cell = row.createCell(colnum++);
		cell.setCellValue("钻石");
		cell = row.createCell(colnum++);
		cell.setCellValue("注册时间");
		cell = row.createCell(colnum++);
		cell.setCellValue("最后登录时间");
		cell = row.createCell(colnum++);
		cell.setCellValue("建筑");
		cell = row.createCell(colnum++);
		cell.setCellValue("好友数");
		cell = row.createCell(colnum++);
		cell.setCellValue("背包物品");
		
		// data
		CellStyle wrapTextStyle = sheet.getWorkbook().createCellStyle();
		wrapTextStyle.setWrapText(true);
		for (Player player : players) {
			colnum = 0;
			row = sheet.createRow(rownum++);
			cell = row.createCell(colnum++);
			cell.setCellValue(String.valueOf(player.getId())); // 玩家id
			cell = row.createCell(colnum++);
			cell.setCellValue(player.getName()); // 玩家名
			cell = row.createCell(colnum++);
			cell.setCellValue(sexOf(player.getSex())); // "性别"
			cell = row.createCell(colnum++);
			cell.setCellValue(player.getLevel()); // 等级
			cell = row.createCell(colnum++);
			cell.setCellValue(player.getGold()); // "现金"
			cell = row.createCell(colnum++);
			cell.setCellValue(player.getStone()); // 钻石
			cell = row.createCell(colnum++);
			cell.setCellValue(player.getCreateTime()); // 注册时间
			cell = row.createCell(colnum++);
			cell.setCellValue(player.getLastLoginTime()); // 最后登录时间
			cell = row.createCell(colnum++);
//			cell.setCellStyle(wrapTextStyle);
			cell.setCellValue(wrapBuildings(player.getBuildings())); // 建筑
			cell = row.createCell(colnum++);
			cell.setCellValue(player.getFriends().size()); // 好友数
			cell = row.createCell(colnum++);
//			cell.setCellStyle(wrapTextStyle);
			cell.setCellValue(wrapGameItems(items.get(player.getId()))); // 背包物品
		}
	}
	
	static String sexOf(byte sex) {
		switch (sex) {
			case com.xcity.db.entity.Player.MALE:
				return "男";
			case com.xcity.db.entity.Player.FEMALE:
				return "女";
			default:
				return "未知";
		}
	}
	
	static String wrapBuildings(List<Build> buildings) {
		StringBuilder buf = new StringBuilder();
		for (Build b : buildings) {
			buf.append(buildTemplates.get(b.getId()).name)
				.append("(").append(b.getId()).append(")")
				.append("=").append(b.getLevel()).append("级").append(System.lineSeparator());
		}
		return buf.toString();
	}
	
	static String wrapGameItems(List<GameItem> list) {
		StringBuilder buf = new StringBuilder();
		if (list != null) {
			for (GameItem item : list) {
				buf.append(gameItemTemplates.get(item.getItemId()).name)
					.append("(").append(item.getItemId()).append(")")
					.append("=").append(item.getCount()).append("个").append(System.lineSeparator());
			}
		}
		return buf.toString();
	}
	
}
